package com.web.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.opencsv.CSVWriter;
import com.web.common.Dto.BrandPredictDto;
import com.web.common.pojos.Brand;
import com.web.common.pojos.Car;
import com.web.common.responseResult.ResponseResult;
import com.web.common.vo.TotalSaleCounts;
import com.web.mapper.BrandMapper;
import com.web.mapper.CarMapper;
import com.web.service.Task3Service;
import com.web.service.Task4Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * [一句话描述该类的功能]
 *
 * @author : [Lenovo]
 * @version : [v1.0]
 * @createTime : [2024/6/11 上午10:56]
 */
@Service
@Slf4j
public class Task4ServiceImpl extends ServiceImpl<BrandMapper, Brand> implements Task4Service {
    String filePath = "D:\\JAVAwork\\myself_idea_work\\cai-view\\car_view_web\\src\\main\\java\\com\\web\\data\\理想car_sales_data.csv";
    @Autowired
    private BrandMapper brandMapper;

    @Override
    public ResponseResult<TotalSaleCounts> brandPredict(BrandPredictDto brandPredictDto) {
        //实际
        String brandName = "";
        if (!brandPredictDto.getBrandName().equals("无")) {
            brandName = brandPredictDto.getBrandName();
        }
        String algorithmName = brandPredictDto.getAlgorithmName();
        int start = 201812,end = 202404;
        List<Integer> dates = brandMapper.selectDateByBrand(brandName,start,end);
        log.info("data:{}", dates.toString());
        List<Integer> saleCounts = brandMapper.selectCountByDateAndBrand(brandName,start,end);
        log.info("sale_count{}", saleCounts.toString());
        //writeDataToCsv(dates, saleCounts);
        List<String> datesAsString = dates.stream()
                .map(date -> {
                    String year = String.format("%04d", date / 100);
                    String month = String.format("%02d", date % 100);
                    return year + "年" + month + "月";
                })
                .collect(Collectors.toList());
        //预测
        //TODO
        List<String> predictDates = new ArrayList<>();
        for (int i =1;i<=6;i++)
        {
            predictDates.add("2024年"+(4+i)+"月");
        }
        List<Integer> predictSaleCounts = new ArrayList<>();
        if (algorithmName.equals("1")&&brandName.length()>0)
        {
            String filePath ="D:\\ciew\\brandpre\\LSTM_predict";
            Integer[] LSTMOneIntegers = LSTMReadPredictionData(brandName, filePath);
            predictSaleCounts.addAll(List.of(LSTMOneIntegers));
        }else if (algorithmName.equals("2")&&brandName.length()>0)
        {
            String filePath ="D:\\ciew\\brandpre\\gm_predict";
            Integer[] GMIntegers = GMReadPredictionData(brandName, filePath);
            predictSaleCounts.addAll(List.of(GMIntegers));
        }/*else if (algorithmName.equals("3"))
        {

        }*/


        datesAsString.addAll(predictDates);
        saleCounts.addAll(predictSaleCounts);


        TotalSaleCounts totalSaleCounts = new TotalSaleCounts();
        totalSaleCounts.setDates(datesAsString);
        totalSaleCounts.setSaleCounts(saleCounts);
        return ResponseResult.okResult(totalSaleCounts);
    }
    public static Integer[] GMReadPredictionData(String brandName, String directoryPath) {
        File directory = new File(directoryPath);
        File[] files = directory.listFiles((dir, name) -> name.startsWith(brandName) && name.endsWith(".txt"));

        File targetFile = files[0];
        List<Integer> predictions = new ArrayList<>();

        try (Scanner scanner = new Scanner(targetFile)) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                Pattern pattern = Pattern.compile("\\[(\\d+\\.\\d+)\\]");
                Matcher matcher = pattern.matcher(line);

                if (matcher.find()) {
                    double number = Double.parseDouble(matcher.group(1)); // 提取方括号内的浮点数
                    int roundedNumber = (int) Math.round(number); // 四舍五入到整数
                    predictions.add(roundedNumber);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return null; // 处理数字格式异常的逻辑
        }

        return predictions.toArray(new Integer[0]);
    }
    public Integer[] LSTMReadPredictionData(String brandName, String directoryPath) {
        File directory = new File(directoryPath);
        File[] files = directory.listFiles((dir, name) -> name.startsWith(brandName) && name.endsWith(".txt"));
        File targetFile = files[0];
        List<Integer> predictions = new ArrayList<>();

        try (Scanner scanner = new Scanner(targetFile)) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                Pattern pattern = Pattern.compile("(\\d{4}-\\d{2}):\\s*(\\d+)");
                Matcher matcher = pattern.matcher(line);

                if (matcher.find()) {
                    int number = Integer.parseInt(((Matcher) matcher).group(2)); // 解析为整数
                    predictions.add(number);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return null; // 或者处理数字格式异常的逻辑
        }
        return predictions.toArray(new Integer[0]);
    }
    public void writeDataToCsv(List<Integer> dates, List<Integer> saleCounts) {
        try {
            // 创建FileWriter对象
            FileWriter writer = new FileWriter(filePath);

            // 创建CSVWriter对象
            CSVWriter csvWriter = new CSVWriter(writer);

            // 写入表头
            String[] header = {"Date", "Sale Count"};
            csvWriter.writeNext(header);

            // 确保两个列表长度相同，避免索引越界
            int size = Math.min(dates.size(), saleCounts.size());

            // 遍历列表，写入数据
            for (int i = 0; i < size; i++) {
                String[] data = {String.valueOf(dates.get(i)), String.valueOf(saleCounts.get(i))};
                csvWriter.writeNext(data);
            }

            // 关闭CSVWriter
            csvWriter.close();
            log.info("Data has been written to CSV file successfully.");
        } catch (IOException e) {
            log.error("Error occurred while writing to CSV file: ", e);
        }
    }
}
